day50 |
您所在的位置:网站首页 › pagehelper多表分页 没出现table_count › day50 |
今日内容
0 复习昨日 一、分页插件 二、ORM映射【重点】 三、多表联查 【重点】 四、动态SQL 【重点】 五、$和# 零、复习昨日mybatis orm框架,作用于持久层,高效开发,只关注sql,其他不用关心 思考MyBatis到底帮你省了哪些事情? jdbc第四步sql自己编写之外,其他mybatis都做了… 接口文件和映射文件如何关联? namespace 接口文件中方法又是如何和映射文件中的语句关联? 接口的方法名与映射文件标签的id一致 语句执行时入参都可以有哪些?有什么注意事项? 基本类型,String,Map,List,POJO(javabean/对象) 语句执行后返回的有哪些类型?(出参) 基本类型,字符串,对象 BUG: 1 idea中resuorces和test文件不识别手动设置标记 控制台错误提示: MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效。 解决方案,在pom文件中加入配置 UTF-8 补充: mapper文件位置mapper映射文件放置位置有两个 resources(推荐)java 如果使用这种,还需再pom文件加入build设置,让idea加载java下的xml文件myabtis-config.xml文件加载映射文件时也要两种方案 使用 但是这种写法,会随着项目模块的增多,这个地方也会随之配置增多 使用 这种写法可以一次加载一个包下的所有映射文件,但是包结构要与接口文件包结构一致 总结,以后就按照以下写法配置: 映射文件全部放在resourcesresources下放映射文件包结构要与java放接口文件包结构一致文件名要一致 一、分页插件现在我们要学习使用一个常用的mybatis的插件 --> 分页插件-PageHelper 最早: findAll() ---> 查全部 后来要分页: findAll(pageNo,pageSize) ---> 改动SQL 加上 limit x,y 还行count(*)来计数使用分页插件之后,只编写正常的查询SQL即可,关于分页的操作插件会自动完成. 引入依赖 com.github.pagehelper pagehelper 5.3.0全局配置文件使用插件 在查询时使用分页功能 public interface UserMapper { List findAll(); } select * from tb_user @Test public void findAll() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 【在执行查询前设置】 // 参数1: 当前页 // 参数2: 每页大小 PageHelper.startPage(2,2); List all = mapper.findAll( ); for (User user : all) { System.out.println(user ); } }mybatis插件是对运行时某一点进行拦截 pagehelper插件是拦截运行时发出的SQL,自动在SQL后面拼接关键词 后续还可以获得更新消息的分页数据,比如共多少条数据?共多少页?当前页?下一页?目前是不是第一页? @Test public void findAll() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 【在执行查询前设置】 // 参数1: 当前页 // 参数2: 每页大小 PageHelper.startPage(2,2); // 执行查询全部 List userList = mapper.findAll( ); // 后续可以获得更详细的信息 PageInfo pageInfo = new PageInfo(userList); System.out.println(pageInfo ); // 获得总条数 System.out.println(pageInfo.getTotal() ); // 获得总页数 System.out.println(pageInfo.getPages() ); // 获得总数据(当前页中的总数据) System.out.println(pageInfo.getList() ); }ps: 可以看源码,中国人开发,注释非常好理解 二、ORM映射 2.1 MyBatis自动ORM失效MyBatis只能自动维护库表”列名“与”属性名“相同时的一一对应关系,二者不同时,无法自动ORM。 自动ORM失效![]() 在SQL中使用 as 为查询字段添加列别名,以匹配属性名。 select id as idd,username,password,phone,create_time,sex,money from tb_user where id = #{id} 2.3 方案二:结果映射(ResultMap - 查询结果的封装规则)通过< resultMap id=“” type=“” >映射,匹配列名与属性名。 select id,username,password,phone,create_time,sex,money from tb_user where id = #{id} 三、 多表联查 【重点】表关系: 一对一,一对多,多对多 多表联查的SQL 3.1 OneToOne需求: 实现一对一查询,查询订单以及对应的用户信息 数据: tb_user表, tb_order表 关系: 用户 —> 订单 (1 VS N) 一个用户有多个订单 订单 —> 用户 (1 VS 1) 一个订单只会属于一个人 tb_user表 CREATE TABLE `tb_user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号', `username` varchar(10) DEFAULT NULL COMMENT '用户名', `password` varchar(10) DEFAULT NULL COMMENT '密码', `phone` varchar(11) DEFAULT NULL COMMENT '手机号', `create_time` date DEFAULT NULL COMMENT '注册时间', `money` double(10,2) DEFAULT NULL COMMENT '账户余额' PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8;tb_order表 CREATE TABLE `tb_order` ( `oid` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单编号', `order_time` datetime DEFAULT NULL COMMENT '订单时间', `order_desc` varchar(255) DEFAULT NULL COMMENT '订单详情', `uid` int(11) DEFAULT NULL COMMENT '关联用户id', PRIMARY KEY (`oid`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; INSERT INTO `tb_order` VALUES (1, '2022-11-17 15:06:29', '笔记本电脑', 1); INSERT INTO `tb_order` VALUES (2, '2022-12-16 11:00:41', 'Cherry键盘', 1); INSERT INTO `tb_order` VALUES (3, '2022-12-16 11:01:23', 'Logi鼠标', 2);实体类 public class Order { private int oid; private Date orderTime; private String orderDesc; private int uid; // set get... }但是上面的实体类,只有订单信息,我们要查询的是订单和用户! 上面的类就无法展现全部数据,所以需要扩展类 public class OrderVO extends Order { private User user; // set get }OrderMapper.java接口文件 public interface OrderMapper { OrderVO findOrderWithUserById(int oid); }OrderMapper.xml映射文件 SELECT o.*, u.* FROM tb_order o, tb_user u WHERE o.uid = u.id AND o.oid = 1测试 @Test public void findOrderWithUserById() { OrderMapper mapper = sqlSession.getMapper(OrderMapper.class); OrderVO orderVO = mapper.findOrderWithUserById(1); // 获得订单信息 int oid = orderVO.getOid( ); System.out.println("oid = " + oid); Date orderTime = orderVO.getOrderTime( ); System.out.println("orderTime = " + orderTime); String orderDesc = orderVO.getOrderDesc( ); System.out.println("orderDesc = " + orderDesc); // 获得订单一家关联的用户信息 User user = orderVO.getUser( ); System.out.println(user ); } 3.2 OneToMore需求: 一对多,查询用户关联查询出所有的订单 SELECT * FROM tb_user u LEFT JOIN tb_order o ON u.id = o.uid WHERE u.id = 3目的查询用户,以及关联多个订单,User类不够展现全部数据,那么就创建扩展类UserVO,UserVO类继承User就可以存储用户信息,还需要再UserVO类中添加Order类来存储信息,但是!!不是一个Order类,因为是一对多,一个用户关联多个订单,所有要设置List User扩展实体类 public class UserVO extends User{ private List orderList; @Override public String toString() { String s = super.toString( ); return s +" \r\n UserVO{" + "orderList=" + orderList + '}'; } public List getOrderList() { return orderList; } public void setOrderList(List orderList) { this.orderList = orderList; } }UserMapper.java接口 public interface UserMapper { UserVO findUserWithOrdersById(int id); }UserMapper.xml映射文件 SELECT * FROM tb_user u LEFT JOIN tb_order o ON u.id = o.uid WHERE u.id = #{id} 3.3 关联查询总结正常封装使用resultMap 一对一封装使用association 一对多封装使用collection 四、动态SQL【重点】动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。 自己话理解: 帮助我们拼接SQL 常见的动态SQL语法 SQL片段(官方不是在动态SQL章节)where , ifsettrimforeach 4.1 SQL片段这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 自己的话: 减少代码重复,主要用于抽取字段,表名等 id, username, password, phone, create_time, money, sex select from tb_user 4.2 ifif就是用来判断,主要用于判断要不要拼接对应的条件语句 -- 需求:查询用户,条件是money=1000,如果密码不为空,也根据密码查 select * from tb_user where money = 1000 select * from tb_user where money = 1000 and password= '123456'UserMapper.java接口方法 public interface UserMapper { /** * 演示if动态sql */ List findByMap(HashMap map); }UserMapper.xml select from tb_user where money = #{money} and password = #{password}测试 /** * if动态sql */ @Test public void showIf() { UserMapper userMapper = sqlSession.getMapper(UserMapper.class); HashMap map = new HashMap( ); map.put("money",1000); List list = userMapper.findByMap(map); for (User user : list) { System.out.println(user ); } } 4.3 where如果说只有if,可能会出现这么一种情况 SELECT * FROM tb_user WHERE多出一个where关键词!! 所以我们需要一个智能的,有条件时帮我们拼接where关键词,没有条件查询时,不拼接where select from tb_user sex = #{sex}所以一般会where和if一起用 4.4 set用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。 UserMapper.java接口方法 public interface UserMapper { int updateUser(User user); }UserMapper.xml update tb_user username = #{username}, password = #{password}, phone = #{phone}, create_time = #{createTime}, money = #{money}, sex = #{sex}, where id = #{id}测试 @Test public void testUpdate(){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = new User( ); user.setId(1); // 只更新这个2字段,其他字段不动 user.setUsername("QF"); user.setPassword("qf666"); int i = mapper.updateUser(user); System.out.println(i > 0?"OK":"ERR" ); // 增删改要提交 sqlSession.commit(); } 4.5 foreach场景: 批量删除 delete from tb_user where id in (1,2,3,...); String sql = "delete from tb_user where id in ("; int iMax = idsArr.length - 1;// 最大下标 for (int i = 0; i sql += ","; } else { sql += ")"; } }UserMapper.java public interface UserMapper { // 为了演示动态sql foreach int deleteBatch(List ids); }UserMapper.xml delete from tb_user where id in #{id}测试 /** * 测试foreach */ @Test public void testForeach(){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); ArrayList list = new ArrayList( ); list.add(31); list.add(32); list.add(33); int i = mapper.deleteBatch(list); System.out.println("i = " + i); System.out.println(i > 0?"OK":"ERR" ); // 增删改要提交 sqlSession.commit(); } 任务 使用项目中的表,重复1遍 合同加房屋实现多表联查 做笔记,写注释,画图标记 使用项目中的表,重复1遍 合同加房屋实现多表联查 做笔记,写注释,画图标记 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |